package com.mask.example.controller;

import com.mask.token.common.Result;
import com.mask.token.model.MaskUserDetails;
import com.mask.token.service.MaskTokenService;
import com.mask.example.service.CustomUserDetailsService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

/**
 * 认证控制器示例
 * 展示如何在用户项目中实现登录业务逻辑
 *
 * @author mask
 * @since 1.0.0
 */
@Slf4j
@RestController
@RequestMapping("/api/auth")
@RequiredArgsConstructor
public class AuthController {

    private final MaskTokenService tokenService;
    private final CustomUserDetailsService userDetailsService;
    private final PasswordEncoder passwordEncoder;

    /**
     * 登录接口
     * 用户需要根据自己的业务逻辑实现
     */
    @PostMapping("/login")
    public Result<Map<String, Object>> login(@RequestBody LoginRequest request) {
        try {
            // 1. 验证用户凭据（这里需要根据实际业务逻辑实现）
            UserDetails userDetails = userDetailsService.loadUserByUsername(request.getUsername());
            
            if (!passwordEncoder.matches(request.getPassword(), userDetails.getPassword())) {
                return Result.fail(401, "用户名或密码错误");
            }
            
            // 2. 转换为MaskUserDetails
            MaskUserDetails maskUserDetails = (MaskUserDetails) userDetails;
            maskUserDetails.setDeviceId(request.getDeviceId());
            
            // 3. 生成Token
            String accessToken = tokenService.generateAccessToken(maskUserDetails);
            String refreshToken = tokenService.generateRefreshToken(maskUserDetails);
            
            // 4. 返回结果
            Map<String, Object> data = new HashMap<>();
            data.put("accessToken", accessToken);
            data.put("refreshToken", refreshToken);
            data.put("tokenType", "Bearer");
            data.put("expiresIn", 7200);
            
            return Result.success("登录成功", data);
        } catch (Exception e) {
            log.error("登录失败", e);
            return Result.fail(401, "用户名或密码错误");
        }
    }

    /**
     * 刷新Token
     */
    @PostMapping("/refresh")
    public Result<Map<String, Object>> refreshToken(@RequestBody RefreshTokenRequest request) {
        try {
            if (!tokenService.validateToken(request.getRefreshToken())) {
                return Result.fail(401, "无效的Refresh Token");
            }
            
            String username = tokenService.getUsernameFromToken(request.getRefreshToken());
            if (username == null) {
                return Result.fail(401, "无法从Token中获取用户信息");
            }
            
            // 重新加载用户信息
            UserDetails userDetails = userDetailsService.loadUserByUsername(username);
            MaskUserDetails maskUserDetails = (MaskUserDetails) userDetails;
            maskUserDetails.setDeviceId(request.getDeviceId());
            
            String newAccessToken = tokenService.refreshToken(request.getRefreshToken(), maskUserDetails);
            
            Map<String, Object> data = new HashMap<>();
            data.put("accessToken", newAccessToken);
            data.put("tokenType", "Bearer");
            data.put("expiresIn", 7200);
            
            return Result.success("Token刷新成功", data);
        } catch (Exception e) {
            log.error("Token刷新失败", e);
            return Result.fail(500, "Token刷新失败: " + e.getMessage());
        }
    }

    /**
     * 注销登录
     */
    @PostMapping("/logout")
    public Result<Void> logout(HttpServletRequest request) {
        String token = com.mask.token.util.MaskTokenUtil.getTokenFromRequest(request);
        if (token != null) {
            tokenService.logout(token);
        }
        return Result.success("注销成功", null);
    }

    /**
     * 获取当前用户信息
     */
    @GetMapping("/userinfo")
    public Result<Map<String, Object>> getUserInfo() {
        org.springframework.security.core.Authentication auth = 
            org.springframework.security.core.context.SecurityContextHolder.getContext().getAuthentication();
        
        if (auth == null || !auth.isAuthenticated()) {
            return Result.fail(401, "未认证");
        }
        
        MaskUserDetails userDetails = (MaskUserDetails) auth.getPrincipal();
        
        Map<String, Object> data = new HashMap<>();
        data.put("userId", userDetails.getUserId());
        data.put("username", userDetails.getUsername());
        data.put("email", userDetails.getEmail());
        data.put("phone", userDetails.getPhone());
        data.put("nickname", userDetails.getNickname());
        data.put("avatar", userDetails.getAvatar());
        data.put("authorities", userDetails.getAuthorities());
        
        return Result.success(data);
    }

    /**
     * 登录请求对象
     */
    public static class LoginRequest {
        private String username;
        private String password;
        private String deviceId;

        // Getters and Setters
        public String getUsername() { return username; }
        public void setUsername(String username) { this.username = username; }
        public String getPassword() { return password; }
        public void setPassword(String password) { this.password = password; }
        public String getDeviceId() { return deviceId; }
        public void setDeviceId(String deviceId) { this.deviceId = deviceId; }
    }

    /**
     * 刷新Token请求对象
     */
    public static class RefreshTokenRequest {
        private String refreshToken;
        private String deviceId;

        // Getters and Setters
        public String getRefreshToken() { return refreshToken; }
        public void setRefreshToken(String refreshToken) { this.refreshToken = refreshToken; }
        public String getDeviceId() { return deviceId; }
        public void setDeviceId(String deviceId) { this.deviceId = deviceId; }
    }
}
